﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//define convertible string type
using ArgumentArray = System.Collections.Generic.List<string>;

/**
*@file       gwcommandline.h
*@brief      parse command line arguments( format like: -x 780 -y555 )
*
*@author     graywind
*@version    1.0.0.0
*@data       2012/01/08
*/

namespace gwBedrockApp
{
    public class gwCommandLine
    {
        #region private
        //arguments number
        private int m_iArgNum;
        //array of convertible strings
        private ArgumentArray m_ArgArray = new ArgumentArray();

        /// <summary>
        /// find the option specificed by user
        /// </summary>
        /// <param name="option">name of option</param>
        /// <returns>int (the index of option in the array(return -1 if failed))</returns>
        private int FindIndex(string option)
        {
            if (m_ArgArray.Count > 0)
            {
                for (int i = 0; i < m_ArgArray.Count; ++i)
                {
                    m_strLastError = string.Empty;
                    if (m_ArgArray[i].Equals(option) == true)
                        return i + 1;
                }

                m_strLastError = m_strOptionNotFound;
            }
            else
                m_strLastError = m_strOptionRequire;

            return gwBedrockUtil.gwCommon.gwInvalidIndex;
        }
        #endregion

        #region protected
        //last error string
        protected string m_strLastError = string.Empty;
        //this means can't find argument follow the option
        protected const string m_strOptionNotFound = "Option not found!";
        //this error means there are not any options
        protected const string m_strOptionRequire = "Option require!";
        #endregion

        #region public

        #region constructor
        /// <summary>
        /// destructor
        /// </summary>
        public gwCommandLine()
        {
            m_strLastError = string.Empty;
            m_iArgNum = 0;
        }
        /// <summary>
        /// construct from standard command line
        /// </summary>
        /// <param name="args">arguments</param>
        public gwCommandLine(string[] arguments)
        {
            if (arguments.Length > 0)
            {
                string cmdLine = ConvertCmdArgToString(arguments);
                string[] args = cmdLine.Split(new char[2] { '-', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string arg in args)
                {
                    m_ArgArray.Add(arg);
                }

                m_iArgNum = (args.Length - 1) / 2;
            }
        }
        /// <summary>
        /// construct from a string object
        /// </summary>
        /// <param name="cmdLine">string object through the ConvertCmdArgToString() function</param>
        public gwCommandLine(string cmdLine)
        {
            string[] args = cmdLine.Split(new char[2] { '-', ' ' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string arg in args)
            {
                m_ArgArray.Add(arg);
            }

            m_iArgNum = (args.Length - 1) / 2;
        }
        /// <summary>
        /// copy constructor
        /// </summary>
        /// <param name="rhs">another gwCommandLine object</param>
        public gwCommandLine(gwCommandLine rhs)
        {
            m_iArgNum = rhs.m_iArgNum;
            foreach (string arg in rhs.m_ArgArray)
            {
                m_ArgArray.Add(arg);
            }
        }
        /// <summary>
        /// convert the standard command line arguments to a string object
        /// </summary>
        /// <param name="args">arguments</param>
        /// <returns>string object</returns>
        public static string ConvertCmdArgToString(string[] args)
        {
            StringBuilder options = new StringBuilder();
            foreach (string arg in args)
            {
                options.Append(arg);
                options.Append(" ");
            }

            return options.ToString();
        }
        #endregion

        #region external property
        /// <summary>
        /// get arguments number
        /// </summary>
        public int ArgumentsNumber
        {
            get
            {
                return m_iArgNum;
            }
            protected set
            {
                m_iArgNum = value;
            }
        }
        /// <summary>
        /// get last error
        /// </summary>
        public string LastError
        {
            get
            {
                return m_strLastError;
            }
            protected set
            {
                m_strLastError = value;
            }
        }
        #endregion

        #region external call
        /// <summary>
        /// get the file name
        /// </summary>
        /// <returns></returns>
        public string GetFileName()
        {
            return System.Diagnostics.Process.GetCurrentProcess().ProcessName;
        }
        /// <summary>
        /// get the option value and convert to bool
        /// </summary>
        /// <param name="Option"></param>
        /// <param name="defautValue"></param>
        /// <returns></returns>
        public bool GetBool(string Option, bool defautValue)
        {
            int index = FindIndex(Option);
            if (index != gwBedrockUtil.gwCommon.gwInvalidIndex)
            {
                bool optionValue = bool.Parse(m_ArgArray[index]);
                return optionValue;
            }

            return defautValue;
        }
        /// <summary>
        /// get the optio value and convert to bool
        /// </summary>
        /// <param name="Option"></param>
        /// <returns></returns>
        public bool GetBool(string Option)
        {
            return GetBool(Option, false);
        }
        /// <summary>
        /// get the option value and convert to int
        /// </summary>
        /// <param name="Option"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public int GetInt(string Option, int defaultValue)
        {
            int index = FindIndex(Option);
            if (index != gwBedrockUtil.gwCommon.gwInvalidIndex)
            {
                int optionValue = int.Parse(m_ArgArray[index]);
                return optionValue;
            }

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to int
        /// </summary>
        /// <param name="Option"></param>
        /// <returns></returns>
        public int GetInt(string Option)
        {
            return GetInt(Option, 0);
        }
        /// <summary>
        /// get the option value and convert to float
        /// </summary>
        /// <param name="Option"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public float GetFloat(string Option, float defaultValue)
        {
            int index = FindIndex(Option);
            if (index != gwBedrockUtil.gwCommon.gwInvalidIndex)
            {
                float optionValue = float.Parse(m_ArgArray[index]);
                return optionValue;
            }

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to float
        /// </summary>
        /// <param name="Option"></param>
        /// <returns></returns>
        public float GetFloat(string Option)
        {
            return GetFloat(Option, 0.0f);
        }
        /// <summary>
        /// get the option value and convert to string
        /// </summary>
        /// <param name="Option"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public string GetString(string Option, string defaultValue)
        {
            int index = FindIndex(Option);
            if (index != gwBedrockUtil.gwCommon.gwInvalidIndex)
            {
                return m_ArgArray[index];
            }

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to string
        /// </summary>
        /// <param name="Option"></param>
        /// <returns></returns>
        public string GetString(string Option)
        {
            return GetString(Option, string.Empty);
        }
        /// <summary>
        /// get the option value and convert to bool
        /// </summary>
        /// <param name="index"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public bool GetBoolByIndex(int index, bool defaultValue)
        {
            if (index <= m_ArgArray.Count - 1)
                return bool.Parse(m_ArgArray[index]);

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to bool
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool GetBoolByIndex(int index)
        {
            return GetBoolByIndex(index, false);
        }
        /// <summary>
        /// get the option value and convert to int
        /// </summary>
        /// <param name="index"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public int GetIntByIndex(int index, int defaultValue)
        {
            if (index <= m_ArgArray.Count - 1)
                return int.Parse(m_ArgArray[index]);

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to int
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public int GetIntByIndex(int index)
        {
            return GetIntByIndex(index, 0);
        }
        /// <summary>
        /// get the option value and convert to float
        /// </summary>
        /// <param name="index"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public float GetFloatByIndex(int index, float defaultValue)
        {
            if (index <= m_ArgArray.Count - 1)
                return float.Parse(m_ArgArray[index]);

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to float
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public float GetFloatByIndex(int index)
        {
            return GetFloatByIndex(index, 0.0f);
        }
        /// <summary>
        /// get the option value and convert to string
        /// </summary>
        /// <param name="index"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public string GetStringByIndex(int index, string defaultValue)
        {
            if (index <= m_ArgArray.Count - 1)
                return m_ArgArray[index];

            return defaultValue;
        }
        /// <summary>
        /// get the option value and convert to string
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public string GetStringByIndex(int index)
        {
            return GetStringByIndex(index, string.Empty);
        }
        #endregion

        #endregion
    }
}